Linux webm002.cluster126.gra.hosting.ovh.net 6.18.39-ovh-vps-grsec-zfs+ #1 SMP PREEMPT_DYNAMIC Tue Jul 21 12:03:15 CEST 2026 x86_64
/
home
/
ariannadhf
/
www
/
wp-content
/
plugins
/
admin-menu-editor
/
customizables
/
Controls
/
/home/ariannadhf/www/wp-content/plugins/admin-menu-editor/customizables/Controls/Control.php
<?php namespace YahnisElsts\AdminMenuEditor\Customizable\Controls; use YahnisElsts\AdminMenuEditor\Customizable\Rendering\Context; use YahnisElsts\AdminMenuEditor\Customizable\Rendering\Renderer; use YahnisElsts\AdminMenuEditor\Customizable\Settings; use YahnisElsts\AdminMenuEditor\Customizable\Settings\AbstractSetting; use YahnisElsts\AdminMenuEditor\Customizable\Settings\Setting; abstract class Control extends UiElement implements ControlContainer { use Toggleable { isEnabled as private traitIsEnabled; } /** * @var string Type of the control */ protected $type = 'abstract'; /** * @var AbstractSetting[] */ protected $settings = []; /** * @var null|Binding */ protected $mainBinding = null; /** * @var string|null Name of the Knockout component that renders this control. */ protected $koComponentName = null; /** * @var string|null */ protected $label = null; /** * @var bool Whether this control has a specific, well-defined form element * that is the main input and needs an associated label. */ protected $hasPrimaryInput = false; /** * @var array List of CSS classes to apply to the primary input element. */ protected $inputClasses = []; /** * @var array List of HTML attributes to add to the input element. */ protected $inputAttributes = []; protected static $totalInstances = 0; protected $instanceNumber = 0; public function __construct($settings = [], $params = [], $children = []) { $this->instanceNumber = ++static::$totalInstances; parent::__construct($params, $children); $this->settings = $settings; if ( !empty($this->settings) ) { if ( isset($params['mainSetting']) ) { $this->mainBinding = $this->settings[$params['mainSetting']]; } else { $this->mainBinding = reset($this->settings); } } //Label if ( isset($params['label']) ) { $this->label = $params['label']; } //Description if ( isset($params['description']) ) { $this->description = $params['description']; } //Enabled/disabled $this->parseEnabledParam($params); //ID. It can be assigned automatically if the control has a plain main setting (not a reference). if ( $this->id === '' ) { if ( $this->mainBinding instanceof AbstractSetting ) { $this->id = preg_replace('/[^a-z0-9\-_]+/i', '_', $this->mainBinding->getId()); //The ID should not start with a number because it *could* //be used as an HTML element ID. if ( preg_match('/^[0-9]/', $this->id) ) { $this->id = 'c' . $this->id; } } } //Input classes if ( isset($params['inputClasses']) ) { $this->inputClasses = (array)$params['inputClasses']; } //Input attributes if ( isset($params['inputAttributes']) ) { $this->inputAttributes = (array)$params['inputAttributes']; } } abstract public function renderContent(Renderer $renderer, Context $context); public function getInputClasses(?Context $context = null): array { return $this->inputClasses; } public function getHtmlIdBase(?Context $context = null) { //Note that this is not necessarily the same as the ID attribute //of the HTML element generated by this control. if ( $this->id === '' ) { $generatedId = ''; if ( $this->mainBinding && $context ) { $path = $context->resolveValuePath($this->mainBinding); if ( !empty($path) ) { $generatedId = implode('.', $path); } } else if ( $this->mainBinding instanceof AbstractSetting ) { $generatedId = $this->mainBinding->getId(); } if ( !empty($generatedId) ) { $generatedId = preg_replace('/[^a-z0-9\-_]+/i', '_', $generatedId); //The ID should not start with a number because it *could* //be used as an HTML element ID. if ( preg_match('/^[0-9]/', $generatedId) ) { $generatedId = 'c' . $generatedId; } return $generatedId; } return 'ame_' . $this->type . '_' . $this->instanceNumber; } return parent::getHtmlIdBase($context); } public function getLabel(?Context $context = null): string { if ( isset($this->label) ) { return $this->label; } if ( !empty($this->mainBinding) ) { return $this->mainBinding->resolveLabel($context); } return ''; } public function getLabelTargetId(?Context $context = null) { return $this->getPrimaryInputId($context); } /** * Does this control have an input or other form-related element that * could be meaningfully associated with the control's label? * * @return bool */ public function supportsLabelAssociation() { return $this->hasPrimaryInput; } /** * Whether this control renders its own label as part of its content. * * For example, a checkbox control will usually wrap a label element around * its input element, so it would return true here. * * @return boolean */ public function includesOwnLabel(): bool { return false; } public function parentLabelEnabled() { return $this->supportsLabelAssociation(); } /** * @return AbstractSetting[] */ public function getSettings() { return $this->settings; } /** * @return string */ public function getType() { return $this->type; } /** * @param Context|null $context * @return bool */ public function isEnabled(?Context $context = null) { $enabled = $this->traitIsEnabled($context); if ( !empty($this->mainBinding) ) { $enabled = $enabled && $this->mainBinding->isEditableByUser($context); } return $enabled; } /** * @param Context|null $context * @return string */ public function getPrimaryInputId(?Context $context = null) { if ( !$this->hasPrimaryInput ) { return ''; } return '_ame-cntrl-' . $this->getHtmlIdBase($context); } /** * Generate an HTML tag based on the input settings of this control. * * This is mainly intended for creating input tags, but it also works for textarea tags. * * @param Context $context * @param array<string,mixed> $attributes * @param string $tagName * @param string|null $content * @return string */ protected function buildInputElement( ?Context $context = null, $attributes = [], $tagName = 'input', $content = null ) { //Merge input classes and any classes specified in the $attributes array. $classes = $this->getInputClasses($context); if ( isset($attributes['class']) ) { $classes = array_merge($classes, (array)$attributes['class']); unset($attributes['class']); } $attributes = array_merge( [ 'id' => $this->hasPrimaryInput ? $this->getPrimaryInputId($context) : null, 'class' => $classes, 'name' => $this->getFieldName($context), 'disabled' => !$this->isEnabled($context), //Add the setting ID for the admin customizer module. 'data-ac-setting-id' => $this->getAutoAcSettingId(), ], $attributes, $this->inputAttributes ); return $this->buildTag($tagName, $attributes, $content); } /** * Generate an HTML tag that will serve as the outer container for this control. * * This is intended to be used for fieldset or div tags that wrap the entire control, and it * will include classes and styles from the control's properties. * * @param array $prependClasses * @param array $attributes * @param string $tagName * @return string */ protected function buildContainerElement( array $prependClasses = [], array $attributes = [], string $tagName = 'div' ): string { $mergedAttributes = array_merge( [ 'class' => array_merge($prependClasses, $this->classes), 'style' => $this->styles, ], $attributes ); return $this->buildTag($tagName, $mergedAttributes); } /** * As buildContainerElement(), but specifically for fieldset tags. Adds the enabled/disabled state * if applicable. * * @param Context $context * @param array $prependClasses * @param array $attributes * @return string */ protected function buildFieldsetContainer(Context $context, array $prependClasses = [], array $attributes = []): string { $attributes['disabled'] = !$this->isEnabled($context); $attributes['data-bind'] = $this->makeKoDataBind($this->getKoEnableBinding()); return $this->buildContainerElement($prependClasses, $attributes, 'fieldset'); } protected function getMainSettingValue($default = null, ?Context $context = null) { if ( $this->mainBinding instanceof Setting ) { return $this->mainBinding->getValue($default); } else if ( $this->mainBinding instanceof Settings\WithSchema\SingularSetting ) { return $this->mainBinding->getValue($default); } else if ( $context && $this->mainBinding ) { return $context->resolveValue($this->mainBinding, $default); } return $default; } /** * Generate the "name" attribute value for a form element associated with * this control. * * @param Context|null $context * @param string|null $compositeChildKey Only for composite settings: the key of the child setting. * @param Binding|null $setting The setting shown in the field. Defaults to the main setting. * @return string */ protected function getFieldName(?Context $context = null, $compositeChildKey = null, ?Binding $setting = null) { if ( $setting === null ) { $setting = $this->mainBinding; } if ( !($setting instanceof Binding) ) { return $this->getHtmlIdBase($context); } if ( $context ) { $path = $context->resolveValuePath($setting); if ( empty($path) ) { return $this->getHtmlIdBase($context); } if ( !empty($compositeChildKey) ) { $path[] = $compositeChildKey; } } else if ( $setting instanceof AbstractSetting ) { if ( ($compositeChildKey === null) || ($compositeChildKey === '') ) { $id = $setting->getId(); } else { $id = $setting->getId() . '.' . $compositeChildKey; if ( $setting instanceof Settings\CompositeSetting ) { $child = $setting->getChild($compositeChildKey); if ( $child ) { $id = $child->getId(); } } } //Convert dot notation to array notation. $path = explode('.', $id); } else { return $this->getHtmlIdBase($context); } $root = array_shift($path); if ( empty($path) ) { return $root; } return $root . '[' . implode('][', $path) . ']'; } public function getAutoGroupTitle() { if ( $this->mainBinding instanceof AbstractSetting ) { $customTitle = $this->mainBinding->getCustomGroupTitle(); if ( !empty($customTitle) ) { return $customTitle; } } return $this->getLabel(); } /** * Get a version of this control that is compatible with the Admin Customizer module. * * May return this object if it is already compatible or if there is * no better alternative. * * @return Control */ public function getAdminCustomizerControl() { return $this; } protected function getAutoAcSettingId() { if ( ($this->mainBinding instanceof AbstractSetting) && $this->hasPrimaryInput ) { return $this->mainBinding->getId(); } return null; } protected function getKoObservableExpression($defaultValue, ?AbstractSetting $setting = null) { if ( $setting === null ) { $setting = $this->mainBinding; } if ( !($setting instanceof AbstractSetting) ) { return wp_json_encode($defaultValue); } $settingId = $setting->getId(); return sprintf( '$root.getSettingObservable(%s, %s)', wp_json_encode($settingId), wp_json_encode($defaultValue) ); } protected function makeKoDataBind($bindingValues) { if ( empty($bindingValues) ) { return ''; } $bindings = []; foreach ($bindingValues as $binding => $value) { $bindings[] = sprintf('%s: %s', $binding, $value); } return implode(', ', $bindings); } protected function getJsUiElementType() { return 'control'; } public function serializeForJs(Context $context): array { $result = parent::serializeForJs($context); $label = $this->getLabel(); if ( !empty($label) ) { $result['label'] = $label; } if ( $this->koComponentName === null ) { return $result; } $result['component'] = $this->koComponentName; //Map setting names to IDs. $settingIds = []; $settings = $this->settings; //The main setting is always available as "value". This means that a setting //could be duplicated in the "settings" array, but that should be fine. if ( $this->mainBinding instanceof Binding ) { $settings['value'] = $this->mainBinding; } foreach ($settings as $name => $setting) { //Skip non-string keys. Controls that care about accessing multiple //distinct settings should have custom keys. if ( !is_string($name) ) { continue; } //Recurse into structs and add all child settings separately as "name.child". //However, don't split up composite settings. if ( ($setting instanceof Settings\AbstractStructSetting) && !($setting instanceof Settings\CompositeSetting) ) { foreach ( AbstractSetting::recursivelyIterateSettings($setting, false, $name) as $key => $childSetting ) { $settingIds[$key] = self::serializeBindingForJs($childSetting, $context); } } else if ( $setting instanceof Binding ) { $settingIds[$name] = self::serializeBindingForJs($setting, $context); } } $result['settings'] = $settingIds; //Enabled state or condition. $result['enabled'] = $this->serializeConditionForJs(); //Label association settings for components that display this control as a child. $includesOwnLabel = $this->includesOwnLabel(); if ( $includesOwnLabel ) { $result['includesOwnLabel'] = true; } $labelTargetId = $this->getLabelTargetId(); if ( $this->supportsLabelAssociation() && !empty($labelTargetId) ) { $result['labelTargetId'] = $labelTargetId; } return $result; } protected function getKoComponentParams(): array { $params = parent::getKoComponentParams(); //Primary input ID. if ( $this->hasPrimaryInput ) { $params['primaryInputId'] = $this->getPrimaryInputId(); } //Input classes. $inputClasses = $this->getInputClasses(); if ( !empty($inputClasses) ) { $params['inputClasses'] = $inputClasses; } //Input attributes. if ( !empty($this->inputAttributes) ) { $params['inputAttributes'] = $this->inputAttributes; } return $params; } public function getChildren(): array { return $this->children; } public function getAllDescendants() { foreach ($this->children as $child) { yield $child; if ( $child instanceof ControlContainer ) { yield from $child->getAllDescendants(); } } } public function getAllReferencedSettings(Context $context) { foreach ($this->getSettings() as $setting) { if ( $setting instanceof AbstractSetting ) { yield $setting->getId() => $setting; } else if ( $setting instanceof Binding ) { $option = $context->resolveBinding($setting); if ( $option->isDefined() ) { $resolution = $option->get(); $leafSetting = $resolution->getSetting(); if ( $leafSetting instanceof AbstractSetting ) { yield $leafSetting->getId() => $leafSetting; } } } } foreach ($this->getChildren() as $child) { yield from $child->getAllReferencedSettings($context); } } }